package main

import (
	"database/sql"
	"fmt"
	"log"
	"myapp/pkg"
	"sync"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

// MySQL连接池结构体
type ConnectionPool struct {
	mu          sync.Mutex   // 锁来确保线程安全
	connections chan *sql.DB // 用通道来存储可用连接
	dsn         string       // 数据源名称
	maxConns    int          // 最大连接数
}

// 初始化数据库连接池
func NewConnectionPool(dsn string, maxConns int) (*ConnectionPool, error) {
	pool := &ConnectionPool{
		connections: make(chan *sql.DB, maxConns),
		dsn:         dsn,
		maxConns:    maxConns,
	}

	// 初始化连接池中的连接
	for i := 0; i < maxConns; i++ {
		db, err := sql.Open("mysql", dsn)
		if err != nil {
			return nil, err
		}

		// 配置连接池的最大连接数等
		db.SetMaxOpenConns(maxConns)
		db.SetMaxIdleConns(1)
		db.SetConnMaxLifetime(5 * time.Minute)

		pool.connections <- db // 将连接放入连接池中
	}

	return pool, nil
}

// 从连接池中获取一个数据库连接
func (p *ConnectionPool) Acquire() (*sql.DB, error) {
	p.mu.Lock()
	defer p.mu.Unlock()

	select {
	case db := <-p.connections: // 如果池中有连接，则返回一个连接
		return db, nil
	case <-time.After(5 * time.Second): // 如果等待超时，则返回错误
		return nil, fmt.Errorf("获取数据库连接超时")
	}
}

// 将连接释放回连接池
func (p *ConnectionPool) Release(db *sql.DB) {
	p.mu.Lock()
	defer p.mu.Unlock()

	// 重新放回连接池
	select {
	case p.connections <- db:
	default:
		log.Println("连接池已满，丢弃该连接")
		db.Close() // 丢弃连接
	}
}

// 模拟数据库查询
func queryDB(pool *ConnectionPool, id int) {
	// 获取数据库连接
	db, err := pool.Acquire()
	if err != nil {
		fmt.Printf("任务 %d 获取连接失败: %v\n", id, err)
		return
	}
	defer pool.Release(db) // 使用完连接后释放回池中

	// 执行查询
	fmt.Printf("任务 %d 开始查询\n", id)
	time.Sleep(2 * time.Second) // 模拟查询时间

	// 执行一个简单的查询
	rows, err := db.Query("SELECT NOW()")
	if err != nil {
		fmt.Printf("任务 %d 查询失败: %v\n", id, err)
		return
	}
	defer rows.Close()

	// 打印查询结果
	var now string
	for rows.Next() {
		err := rows.Scan(&now)
		if err != nil {
			fmt.Printf("任务 %d 读取数据失败: %v\n", id, err)
			return
		}
		fmt.Printf("任务 %d 查询结果: %s\n", id, now)
	}
}

var pool *sync.Pool

type Person struct {
	Name string
	Age  int
}

func init() {
	pool = &sync.Pool{
		New: func() interface{} {
			fmt.Println("creating a new person")
			return new(Person)
		},
	}
}

func main() {

	// 待翻译的文本
	query := "你好\n帮我翻译，我要打球"

	// 执行翻译
	result, err := pkg.Translate(query)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	// 打印翻译结果
	fmt.Println("翻译结果:", result)

	for k, v := range result.TransResult {
		fmt.Println(k, v.Src, v.Dst)
	}

	return

	person := pool.Get().(*Person)
	fmt.Printf("get an object from pool:%v\n", person)

	person.Name = "my"
	person.Age = 8

	pool.Put(person)
	person = pool.Get().(*Person)
	fmt.Printf("get an object from pool:%v\n", person)
	person = pool.Get().(*Person)
	fmt.Printf("get an object from pool:%v\n", person)
	person.Name = "my111"
	person.Age = 81

	pool.Put(person)
	person = pool.Get().(*Person)
	fmt.Printf("get an object from pool:%v\n", person)
	person = pool.Get().(*Person)
	fmt.Printf("get an object from pool:%v\n", person)

	return
	// 初始化连接池
	dsn := "root:123456@tcp(localhost:3306)/myappdb?charset=utf8mb4&parseTime=True&loc=Local"
	pool, err := NewConnectionPool(dsn, 10) // 设置最大连接数为 3
	if err != nil {
		log.Fatalf("创建连接池失败: %v\n", err)
	}
	defer pool.Release(nil) // 释放连接池

	// 启动 5 个并发任务，模拟查询
	var wg sync.WaitGroup
	for i := 1; i <= 5; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			queryDB(pool, id)
		}(i)
	}

	// 等待所有任务完成
	wg.Wait()
}
